#if UNITY_EDITOR
using System.IO;
using DL.UICheck.Runtime;
using UnityEngine;
using UnityEditor;

namespace DL.UICheck.Editor
{
    [InitializeOnLoad]
    public static class UICheckTools
    {
        public static UICheckConfig UICheckConfig;
        // public static string ConfigPath = Path.Combine("Assets", "Resources", "UICheckSetting", "UICheckConfig.asset");

        static UICheckTools()
        {
            EditorApplication.delayCall += Initialize;
            EditorApplication.quitting += SaveConfig; // 添加保存配置的回调
        } 

        private static void Initialize()
        {
            LoadOrCreateUIDebugConfig();
            SceneView.duringSceneGui += OnSceneGUI;
        }
        public static void SaveConfig()
        {
            if (UICheckConfig != null)
            {
                EditorUtility.SetDirty(UICheckConfig);
                AssetDatabase.SaveAssets();
            }
        }
        
        private static void LoadOrCreateUIDebugConfig()
        {
            // 尝试从Resources文件夹加载配置
            UICheckConfig = Resources.Load<UICheckConfig>(Path.Combine("UICheckSetting", "UICheckConfig"));

            // 如果配置已存在，直接返回
            if (UICheckConfig != null) return;
            
            // 如果配置不存在，创建一个新的配置文件
            UICheckConfig = ScriptableObject.CreateInstance<UICheckConfig>();
            // 确保Resources文件夹存在
            string resourcesFolderPath = Path.Combine("Assets", "Resources");
            if (!AssetDatabase.IsValidFolder(resourcesFolderPath))
            {
                AssetDatabase.CreateFolder("Assets", "Resources");
            }

            // 确保UICheckSetting子文件夹存在
            string uiCheckSettingFolderPath = Path.Combine(resourcesFolderPath, "UICheckSetting");
            if (!AssetDatabase.IsValidFolder(uiCheckSettingFolderPath))
            {
                AssetDatabase.CreateFolder(resourcesFolderPath, "UICheckSetting");
            }
            
            AssetDatabase.Refresh();
            // 保存新的配置文件到指定路径
            string fullPath = Path.Combine(uiCheckSettingFolderPath, "UICheckConfig.asset");
            AssetDatabase.CreateAsset(UICheckConfig, fullPath);
            AssetDatabase.SaveAssets();
            Debug.Log("Create UICheckConfig asset out path: " + fullPath); 
        }

        private static void OnSceneGUI(SceneView sceneView)
        {
            if (!UICheckConfig.Enbale) return;
            // 查找所有根Canvas（没有父Canvas的）
            var rootCanvases = Object.FindObjectsOfType<Canvas>();
            foreach (var canvas in rootCanvases)
            {
                if ((canvas.transform.parent != null
                        ? canvas.transform.parent.GetComponentInParent<Canvas>()
                        : null) != null)
                    continue; // 跳过嵌套Canvas（由父Canvas处理）
                //处理顶级Canvas
                TraverseCanvas(canvas.transform, 0, null);
            }
        }

        private static void TraverseCanvas(Transform node, int depth, Canvas parentCanvas)
        {
            // 绘制当前Canvas（如果有）
            var canvas = node.GetComponent<Canvas>();
            if (canvas != null)
            {
                //是否需要渲染未激活的Canvas
                if (UICheckConfig.OnlyActive && !canvas.gameObject.activeInHierarchy)
                {
                    return;
                }
                var overflow = false;
                if (parentCanvas != null)
                {
                    //检查是否超出边界
                    overflow = CheckOverflow(parentCanvas.GetComponent<RectTransform>(),
                        node.GetComponent<RectTransform>());
                }

                DrawCanvasBorder(canvas, depth, overflow);
                depth++; // 进入子层级时增加深度
            }
            else
            {
                canvas = parentCanvas;
            }

            // 处理子对象
            foreach (Transform child in node)
            {
                if (child.GetComponent<Canvas>() != null)
                {
                    TraverseCanvas(child, depth, canvas); // 递归处理嵌套Canvas
                }
                else
                {
                    DrawUIElement(child, canvas);
                    TraverseUIElements(child, canvas); // 处理普通UI元素
                }
            }
        }

        private static void DrawCanvasBorder(Canvas canvas, int depth, bool overflow)
        {
            RectTransform rectTransform = canvas.GetComponent<RectTransform>();
            if (rectTransform == null) return;

            Vector3[] corners = new Vector3[4];
            rectTransform.GetWorldCorners(corners);

            // 调整Z轴位置避免重叠
            for (int i = 0; i < corners.Length; i++)
            {
                corners[i] += Vector3.forward * (0.1f * (depth + 1));
            }

            // 选择颜色
            Color color = overflow
                ? UICheckConfig.OverflowColor
                : depth < UICheckConfig.CanvasColors.Length
                    ? UICheckConfig.CanvasColors[depth]
                    : UICheckConfig.CanvasColors[UICheckConfig.CanvasColors.Length - 1];

            // 绘制边框
            Handles.color = color;
            Handles.DrawAAPolyLine(UICheckConfig.Thickness,
                corners[0], corners[1],
                corners[1], corners[2],
                corners[2], corners[3],
                corners[3], corners[0]);

            if (UICheckConfig.DottedLine)
            {
                Handles.DrawDottedLine(corners[0], corners[2], UICheckConfig.Thickness);
                Handles.DrawDottedLine(corners[1], corners[3], UICheckConfig.Thickness);
            }

            // 显示信息
            if (UICheckConfig.Info)
            {
                var originalColor = GUI.color;
                GUI.color = color;
                Handles.Label(corners[1],
                    $"{canvas.name}\n" +
                    $"Layer: {depth}\n" +
                    $"Size: {rectTransform.rect.size}");
                GUI.color = originalColor;
            }
        }

        private static void DrawUIElement(Transform element, Canvas canvas)
        {
            var rectTransform = element.GetComponent<RectTransform>();
            if (rectTransform == null || UICheckConfig.OnlyActive && !element.gameObject.activeInHierarchy) return;

            Vector3[] corners = new Vector3[4];
            rectTransform.GetWorldCorners(corners);

            //超出检查
            var overflow = CheckOverflow(canvas.GetComponent<RectTransform>(),
                rectTransform);
            Handles.color = overflow ? UICheckConfig.OverflowColor : UICheckConfig.UIElementColor;

            Handles.DrawAAPolyLine(UICheckConfig.Thickness,
                corners[0], corners[1],
                corners[1], corners[2],
                corners[2], corners[3],
                corners[3], corners[0]);

            if (UICheckConfig.DottedLine)
            {
                Handles.DrawDottedLine(corners[0], corners[2], UICheckConfig.Thickness);
                Handles.DrawDottedLine(corners[1], corners[3], UICheckConfig.Thickness);
            }

            if (UICheckConfig.Info)
            {
                var originalColor = GUI.color;
                GUI.color = UICheckConfig.UIElementColor;
                Handles.Label(corners[1],
                    $"{rectTransform.name}\n" +
                    $"Size: {rectTransform.rect.size}\n" +
                    $"Pos: {rectTransform.anchoredPosition}");
                GUI.color = originalColor;
            }
        }

        private static void TraverseUIElements(Transform parent, Canvas canvas)
        {
            foreach (Transform child in parent)
            {
                if (child.GetComponent<Canvas>() != null) continue;

                DrawUIElement(child, canvas);
                TraverseUIElements(child, canvas);
            }
        }

        public static void SetCanvasColorsLength(int length)
        {
            if (length <= 0)
            {
                Debug.LogError("Array length must be greater than 0.");
                return;
            }

            Color[] newColors = new Color[length];
            for (int i = 0; i < Mathf.Min(UICheckConfig.CanvasColors.Length, length); i++)
            {
                newColors[i] = UICheckConfig.CanvasColors[i];
            }

            UICheckConfig.CanvasColors = newColors;
        }

        public static void Reset()
        {
            UICheckConfig.ResetData();
        }

        // 边界检测逻辑
        private static bool CheckOverflow(RectTransform parent, RectTransform child)
        {
            // 获取父Canvas的矩形边界
            Rect parentRect = parent.rect;
            // 遍历每个采样点
            for (int x = 0; x <= UICheckConfig.CheckPrecision; x++)
            {
                for (int y = 0; y <= UICheckConfig.CheckPrecision; y++)
                {
                    // 计算采样点的局部坐标
                    var rect = child.rect;
                    Vector2 localPoint = new Vector2(
                        Mathf.Lerp(rect.xMin, rect.xMax, x / (float)UICheckConfig.CheckPrecision),
                        Mathf.Lerp(rect.yMin, rect.yMax, y / (float)UICheckConfig.CheckPrecision)
                    );
                    // 将局部坐标转换为世界坐标
                    Vector3 worldPoint = child.TransformPoint(localPoint);
                    // 将世界坐标转换到父Canvas的局部坐标系
                    Vector2 parentLocalPoint = parent.InverseTransformPoint(worldPoint);

                    // 检查点是否在父Canvas的矩形内
                    if (!parentRect.Contains(parentLocalPoint - UICheckConfig.OverflowThreshold * Vector2.one) &&
                        !parentRect.Contains(parentLocalPoint + UICheckConfig.OverflowThreshold * Vector2.one))
                    {
                        // 如果点超出了父Canvas的边界，返回true
                        return true;
                    }
                }
            }
            // 所有采样点都在父Canvas内，返回false
            return false;
        }
    }
}

#endif
